﻿using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using MugenMvvmToolkit.Ioc;

namespace MugenMvvmToolkit.Interfaces
{
    /// <summary>
    ///     Represent the base interface for ioc container.
    /// </summary>
    public interface IIocAdapter : IDisposable, IServiceProvider
    {
        /// <summary>
        ///     Gets the id of <see cref="IIocAdapter" />.
        /// </summary>
        int Id { get; }

        /// <summary>
        ///     Gets a value indicating whether this instance is disposed.
        /// </summary>
        bool IsDisposed { get; }

        /// <summary>
        ///     Gets the parent ioc adapter.
        /// </summary>
        [CanBeNull]
        IIocAdapter Parent { get; }

        /// <summary>
        ///     Gets the original ioc container.
        /// </summary>
        [NotNull]
        object Container { get; }

        /// <summary>
        ///     Creates a child ioc adapter.
        /// </summary>
        /// <returns>
        ///     An instance of <see cref="IIocAdapter" />.
        /// </returns>
        [NotNull]
        IIocAdapter CreateChild();

        /// <summary>
        ///     Gets an instance of the specified service.
        /// </summary>
        /// <param name="service">The specified service type.</param>
        /// <param name="name">The specified binding name.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        [Pure]
        object Get([NotNull]Type service, string name = null, params IIocParameter[] parameters);

        /// <summary>
        ///     Gets all instances of the specified service.
        /// </summary>
        /// <param name="service">Specified service type.</param>
        /// <param name="name">The specified binding name.</param>
        /// <param name="parameters">The specified parameters.</param>
        /// <returns>An instance of the service.</returns>
        [Pure]
        IEnumerable<object> GetAll([NotNull]Type service, string name = null, params IIocParameter[] parameters);

        /// <summary>
        ///     Indicates that the service should be bound to the specified constant value.
        ///     <param name="service">The specified service type.</param>
        ///     <param name="constValue">The specified value.</param>
        ///     <param name="name">The specified binding name.</param>
        /// </summary>
        void BindToConstant([NotNull]Type service, object constValue, string name = null);

        /// <summary>
        ///     Indicates that the service should be bound to the specified type.
        /// </summary>
        /// <param name="service">The specified service type.</param>
        /// <param name="typeTo">The specified to type</param>
        /// <param name="name">The specified binding name.</param>
        /// <param name="dependencyLifecycle">
        ///     The specified <see cref="DependencyLifecycle" />
        /// </param>
        void Bind([NotNull]Type service, [NotNull] Type typeTo, DependencyLifecycle dependencyLifecycle, string name = null);

        /// <summary>
        ///     Unregisters all bindings with specified conditions for the specified service.
        /// </summary>
        /// <param name="service">The specified service type.</param>
        void Unbind([NotNull]Type service);

        /// <summary>
        ///     Determines whether the specified request can be resolved.
        /// </summary>
        /// <param name="service">The specified service type.</param>
        /// <returns>
        ///     <c>True</c> if the specified service has been resolved; otherwise, <c>false</c>.
        /// </returns>
        [Pure]
        bool CanResolve([NotNull]Type service);
    }
}